package net.lh.contactsserver.controller;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Collection;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.multipart.MultipartFile;

import net.lh.contactsserver.Config;
import net.lh.contactsserver.entity.ApkInfo;
import net.lh.contactsserver.entity.Contact;
import net.lh.contactsserver.service.ContactService;
import net.lh.contactsserver.utils.ApkInfoUtil;

/**
 * APP调用服务器端的入口.
 * 
 * @author hling
 */
@RestController
@RequestMapping(value = "api")
public class ContactController {
	private static Logger logger = LoggerFactory.getLogger(ContactController.class);
	@Autowired
	private ContactService contactService;
	@Autowired
	ApkInfoUtil apkInfoUtil;
	@Autowired
	private Config config;

	/**
	 * 返回通讯录清单
	 * 
	 * @param username
	 * @param password
	 * @return
	 */
	@RequestMapping(value = "u/{username}/{password}", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
	public String list(@PathVariable("username") String username, @PathVariable("password") String password) {
		validateAccessRight(username, password);
		Collection<Contact> list = contactService.list(username, password);
		StringBuffer sb = new StringBuffer();
		for (Contact contact : list) {
			sb.append(",{");
			sb.append(String.format(
					"\"UserName\":\"%1$s\",\"Company\":\"%2$s\",\"Department\":\"%3$s\",\"JobTitle\":\"%4$s\",\"Phone\":\"%5$s\",\"ShortPhone\":\"%6$s\",\"AvatarURL\":\"%7$s\"",
					contact.getName(), contact.getCompany(), contact.getDepartment(), contact.getJobTitle(),
					contact.getMobile1(), contact.getPhone(),
					contact.getAvatarId() == null ? "" : contact.getAvatarId()));
			sb.append("}");
		}
		if (sb.length() > 0) {
			sb.setCharAt(0, '[');
			sb.append("]");
		}
		return sb.toString();
	}

	/**
	 * 校验用户名和访问密码。如果不正确，抛出未授权异常。
	 */
	private void validateAccessRight(String username, String password) {
		if (!contactService.validateUser(username, password)) {
			logger.error("不识别的账号访问：{}/{}", username, password);
			throw new HttpServerErrorException(HttpStatus.UNAUTHORIZED);
		}
	}

	/**
	 * 下载头像文件
	 * 
	 * @param avatar_id
	 *            头像id，格式为"用户名_图像文件的时间戳"。 时间戳是服务器保存的图像文件的修改时间，由服务器提供给客户端。
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "avatar/{avatar_id}", method = RequestMethod.GET)
	public ResponseEntity<byte[]> getAvatar(@PathVariable("avatar_id") String avatar_id) throws IOException {
		if (avatar_id == null) {
			return null;
		}
		if (!avatar_id.contains("_")) {
			return null;
		}
		String userName = avatar_id.substring(0, avatar_id.indexOf("_"));
		File image = contactService.findAvatarFile(userName);
		if (image.exists() && image.isFile()) {
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
			return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(image), headers, HttpStatus.OK);
		} else {
			throw new HttpServerErrorException(HttpStatus.NOT_FOUND);
		}
	}

	/**
	 * 用户上传自己的头像
	 * 
	 * @param username
	 * @param password
	 * @param avatarFile
	 */
	@RequestMapping(value = "avatar/upload", method = RequestMethod.POST)
	public void uploadAvatar(@RequestParam(value = "username", required = true) String username,
			@RequestParam(value = "password", required = true) String password,
			@RequestParam(value = "avatar", required = true) MultipartFile avatarFile) {
		validateAccessRight(username, password);
		if (avatarFile != null) {
			String originalfileName = avatarFile.getOriginalFilename();
			if (!checkFileName(originalfileName, new String[] { ".jpg"/* , ".bmp", ".jpeg", ".png" */ })) {
				throw new HttpServerErrorException(HttpStatus.BAD_REQUEST, "无法处理的文件！");
			}
			String fileExtName = FilenameUtils.getExtension(originalfileName);
			if (StringUtils.isEmpty(fileExtName)) {
				fileExtName = "jpg";
			}
			// 删除旧的头像文件
			contactService.deleteAvatarFile(username);
			// 用提交的新头像更新
			try {
				contactService.saveAvatarFile(username, fileExtName, avatarFile.getInputStream());
			} catch (IOException e) {
				throw new HttpServerErrorException(HttpStatus.BAD_REQUEST, "上传的文件不合法！");
			}
		} else {
			// 没有提交头像，则视为删除头像
			contactService.deleteAvatarFile(username);
		}
		return;
	}

	private boolean checkFileName(String originalfileName, String[] extendNames) {
		if (StringUtils.isEmpty(originalfileName)) {
			logger.error("上传的文件名为空");
			return false;
		}
		if (!StringUtils.endsWithAny(originalfileName, extendNames)) {
			// 上传的文件名不是图像文件
			logger.error("上传的文件扩展名不是APK:" + originalfileName);
			return false;
		}
		return true;
	}

	@RequestMapping(value = "apk", produces = "application/json; charset=UTF-8")
	public ApkInfo getApkInfo() {
		ApkInfo info = apkInfoUtil.load();
		if (info == null || StringUtils.isEmpty(info.getVersionCode())) {
			return null;
		} else {
			return info;
		}
	}

	/**
	 * 下载更新apk文件
	 * 
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "apk/download", method = RequestMethod.GET)
	public ResponseEntity<byte[]> downloadApk(HttpServletRequest request) throws IOException {
		ApkInfo info = apkInfoUtil.load();
		logger.info("接收到APK文件下载请求");
		if (info == null || StringUtils.isBlank(info.getVersionCode())) {
			logger.error("服务器端没有APK版本信息，不能提供下载");
			return null;
		}
		File apkFile = new File(config.getRootPath(), info.getFileName());
		logger.info("下载APK文件路径为{}", apkFile.getCanonicalFile());
		if (apkFile.exists() && apkFile.isFile()) {
			HttpHeaders headers = new HttpHeaders();
			String fileName = info.getFileName();
			String userAgent = request.getHeader("User-Agent");
			if (userAgent.contains("MSIE") || userAgent.contains("Trident") || userAgent.contains("Edge")
					|| userAgent.contains("XiaoMi")) {
				fileName = URLEncoder.encode(fileName, "UTF-8");
				// encode后替换 解决空格问题
				fileName = StringUtils.replace(fileName, "+", "%20");
				if (fileName.length() > 150) {
					fileName = new String(fileName.getBytes("GB2312"), "ISO8859-1");
					fileName = StringUtils.replace(fileName, " ", "%20");
				}
			} else {
				fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
			}
			headers.add("Content-disposition", String.format("attachment; filename=\"%s\"", fileName));
			headers.add("Content-Type", "application/vnd.android.package-archive");
			ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(apkFile), headers,
					HttpStatus.OK);
			return entity;
		} else {
			logger.error("找不到APK文件，可能是服务器路径错误或文件已被删除。");
			throw new HttpServerErrorException(HttpStatus.NOT_FOUND, "下载失败。服务器未找到要下载的文件。");
		}
	}

	/**
	 * 用户删除头像方法
	 * 
	 * @param username
	 * @param password
	 */
	@RequestMapping(value = "avatar/delete", method = RequestMethod.GET)
	public String delAvatar(String username, String password) {
		validateAccessRight(username, password);
		contactService.deleteAvatarFile(username);
		String msg = "删除成功！";
		return msg;
	}
}
